----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:43:33 05/04/2012 
-- Design Name: 
-- Module Name:    top - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity TOP is
generic (
		constant BIT_WIDTH : integer := 32		--DEFAULT: ONE BYTE
			);
Port ( 	


		--DAC_MON
		SCK_DAC			: OUT	STD_LOGIC;
		DIN_DAC			: OUT STD_LOGIC;
		CS_DAC			: OUT STD_LOGIC;	--active low!!
		
		SCL_MUX			: OUT STD_LOGIC;
		SDA_MUX			: OUT STD_LOGIC;
		
		SCL_MON			: OUT STD_LOGIC;
		SDA_MON			: OUT STD_LOGIC;
		
		SSTIN				:	OUT STD_LOGIC;
		SSPIN				:	OUT STD_LOGIC;
		RAMP				:	OUT STD_LOGIC;
		RD_ROWSEL		:	OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
		RD_COLSEL		:	OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
		RD_ENA			:	OUT STD_LOGIC;
		TST_START		:	OUT STD_LOGIC;
		TST_BOIN_CLR	:	OUT STD_LOGIC;
		SIN				:	OUT STD_LOGIC;
		SCLK				:	OUT STD_LOGIC;
		REGCLR			:	OUT STD_LOGIC;
		WR_ADDRCLR		:	OUT STD_LOGIC;
		WR_STRB			:	OUT STD_LOGIC;
		START				:	OUT STD_LOGIC;
		SAMPLESEL		:	OUT STD_LOGIC_VECTOR(5 DOWNTO 1);
		SAMPLESEL_ANY		:	OUT STD_LOGIC;
		PCLK				:	OUT STD_LOGIC;
		WR_ADVCLK		:	OUT STD_LOGIC;
		WR_ENA			:	OUT STD_LOGIC;
		CLR				:	OUT STD_LOGIC;
		SR_SEL			:	OUT STD_LOGIC;
		SR_CLOCK			:	OUT STD_LOGIC;
		SR_CLEAR			:	OUT STD_LOGIC;
		
		MON				:	OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
		LMON				:	OUT STD_LOGIC_VECTOR(19 DOWNTO 16);
		
		

		CLK_40M 				:  in  	STD_LOGIC;
		
		DO						:	IN		STD_LOGIC_VECTOR(16 DOWNTO 1);
		SSPOUT				:	IN		STD_LOGIC;
		RCO					:	IN		STD_LOGIC;
		TRG_16				:	IN		STD_LOGIC;
		TRG					:	IN		STD_LOGIC_VECTOR(4 DOWNTO 1);
		TRGIN					:	IN		STD_LOGIC;	--PULSE IN
		TRGMON				:	IN		STD_LOGIC;
		SHOUT					:	IN		STD_LOGIC;
		TSTOUT				:	IN		STD_LOGIC;
		SW						:	IN		STD_LOGIC_VECTOR(4 DOWNTO 1)	--SWITCH ON THE UNIVERSAL EVAL BOARD.
		
	
		);
end TOP;

architecture Behavioral of TOP is
	--------------------CHIPSCOPE-----------------------------------------
	component ICON
	  PORT (
		 CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);
		 CONTROL1 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)
		 );

	end component;

	component VIO_DAC_MON
	  PORT (
		 CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);
		 CLK : IN STD_LOGIC;
		 SYNC_IN : IN STD_LOGIC_VECTOR(127 DOWNTO 0);
		 SYNC_OUT : OUT STD_LOGIC_VECTOR(127 DOWNTO 0));

	end component;

--	component VIO_TARGET4
--	  PORT (
--		 CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);
--		 CLK : IN STD_LOGIC;
--		 SYNC_IN : IN STD_LOGIC_VECTOR(255 DOWNTO 0);
--		 SYNC_OUT : OUT STD_LOGIC_VECTOR(255 DOWNTO 0));
--
--	end component;
	
	component ILA
	  PORT (
		 CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);
		 CLK : IN STD_LOGIC;
		 TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0));

	end component;
	----------------------------------------------------------------------------
	
	SIGNAL INTERNAL_CHIPSCOPE_CONTROL_VIO_DAC_MON : STD_LOGIC_VECTOR(35 DOWNTO 0);
--	SIGNAL INTERNAL_CHIPSCOPE_CONTROL_VIO_TARGET4 : STD_LOGIC_VECTOR(35 DOWNTO 0);
	SIGNAL INTERNAL_CHIPSCOPE_CONTROL_ILA : STD_LOGIC_VECTOR(35 DOWNTO 0);
	
	SIGNAL INTERNAL_CHIPSCOPE_VIO_DAC_MON_IN : STD_LOGIC_VECTOR(127 DOWNTO 0);
	SIGNAL INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT : STD_LOGIC_VECTOR(127 DOWNTO 0);
	
--	SIGNAL INTERNAL_CHIPSCOPE_VIO_TARGET4_IN : STD_LOGIC_VECTOR(255 DOWNTO 0);
--	SIGNAL INTERNAL_CHIPSCOPE_VIO_TARGET4_OUT : STD_LOGIC_VECTOR(255 DOWNTO 0);
	
	SIGNAL INTERNAL_CHIPSCOPE_ILA_TRIG0 : STD_LOGIC_VECTOR(7 DOWNTO 0);
	
	SIGNAL CLK_COUNTER				: UNSIGNED(3 DOWNTO 0);
	SIGNAL SCK_DAC_INTERNAL				: STD_LOGIC;
	SIGNAL DIN_DAC_INTERNAL				: STD_LOGIC;
	SIGNAL CS_DAC_INTERNAL 			: STD_LOGIC;	--ACTIVE LOW
	
	type DAC_MON_STATE_TYPE is 
		(	
			st_check_state,
			st_input_serial_data	
		);

	signal state     		: DAC_MON_STATE_TYPE := st_check_state;
	
	----------------------------------------------------------------------------

begin
	----------------------------------------------------------------------------
	CHIPSCOPE_ICON : ICON
	port map (
		CONTROL0 => INTERNAL_CHIPSCOPE_CONTROL_VIO_DAC_MON,
		CONTROL1 => INTERNAL_CHIPSCOPE_CONTROL_ILA
		);
		
	CHIPSCOPE_VIO_DAC_MON : VIO_DAC_MON
	PORT MAP(
		CONTROL => INTERNAL_CHIPSCOPE_CONTROL_VIO_DAC_MON,
		CLK => CLK_COUNTER(2),
		SYNC_IN => INTERNAL_CHIPSCOPE_VIO_DAC_MON_IN,
		SYNC_OUT => INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT
	 );
	 
--	CHIPSCOPE_VIO_TARGET4 : VIO_TARGET4
--	  port map (
--		 CONTROL => INTERNAL_CHIPSCOPE_CONTROL_VIO_TARGET4,
--		 CLK => CLK_COUNTER(2),
--		 SYNC_IN => INTERNAL_CHIPSCOPE_VIO_TARGET4_IN,
--		 SYNC_OUT => INTERNAL_CHIPSCOPE_VIO_TARGET4_OUT
--		 );
	 
	CHIPSCOPE_ILA : ILA
	  port map (
		 CONTROL => INTERNAL_CHIPSCOPE_CONTROL_ILA,
		 CLK => CLK_COUNTER(2),
		 TRIG0 => INTERNAL_CHIPSCOPE_ILA_TRIG0
		 );
	----------------------------------------------------------------------------
	
	FREQ_DIV : PROCESS(CLK_40M)
	BEGIN
		IF RISING_EDGE(CLK_40M) THEN
			
			CLK_COUNTER <= CLK_COUNTER + 1;
			
		END IF;
	END PROCESS FREQ_DIV;
	
	----------------------------------------------------------------------------
	
	DAC_MON	: PROCESS(CLK_COUNTER(3))
	variable bit_counter : integer range 0 to BIT_WIDTH := 0;
	--variable cnt : integer range 0 to 7 := 0;
	variable toggle : std_logic;
	variable data_array : std_logic_vector(BIT_WIDTH-1 downto 0);
	variable dac_output_address : integer range 0 to 15 := 0;
	BEGIN
		if rising_edge(CLK_COUNTER(3)) then
			CASE state IS
				when st_check_state =>			
						
					
						if INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT(12) = '1' then	--update all DAC output when it's '1', update single DAC output when it's '0'
							data_array(10 downto 8) := "100";	--control bits for the first chip(update all DACs output with the same value)
							data_array(26 downto 24) := "100";	--control bits for the second chip						
						else	--single update
							dac_output_address := to_integer(unsigned(INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT(11 downto 8)));
							--> (DIN) ||firt chip 16 bits|| (DOUT)-->(DIN) ||second chip 16 bits||
							if dac_output_address <= 7 then	----Output address for fist chip (DC8 -- DC1). Daisy-chain. 
								data_array(13 downto 11) := std_logic_vector(to_unsigned(dac_output_address, 3));	--address bits
								--data_array(29 downto 27) := "000";
								data_array(10 downto 8) := "110";	--control bits(single update) for the first chip
								data_array(26 downto 24) := "000";	--control bits(no operation) for the second chip
							else	--Output address for second chip (DC16 -- DC9)
								--data_array(13 downto 11) := "000"
								data_array(29 downto 27) := std_logic_vector(to_unsigned(dac_output_address-8, 3));
								data_array(10 downto 8) := "000";	--control bits(NOP) 
								data_array(26 downto 24) := "110";	--control bits(SINGLE) 
							end if;
						end if;
						
						data_array(7 downto 0) := INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT(7 downto 0);
						data_array(23 downto 16) := INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT(7 downto 0);
						
						
						if INTERNAL_CHIPSCOPE_VIO_DAC_MON_OUT(13) = '1' then	--to updatE
							CS_DAC_INTERNAL <= '0';
							state <= st_input_serial_data;
						else
							CS_DAC_INTERNAL <= '1';
							state <= st_input_serial_data;
						end if;
						
	

				when st_input_serial_data	=>
					if (bit_counter < (BIT_WIDTH)) then							
						if (toggle = '0') then
							SCK_DAC_INTERNAL <= '0';
							DIN_DAC_INTERNAL <= data_array(BIT_WIDTH-1-bit_counter);		--start from the MSB
							toggle := '1';
						else
							SCK_DAC_INTERNAL <= '1';
							toggle := '0';
							bit_counter := bit_counter + 1;
						end if;
					else
						bit_counter := 0;
						CS_DAC_INTERNAL <= '1';
						state <= st_check_state;
						
					end if;

				when others =>
					CS_DAC_INTERNAL <= '1';
					state <= st_check_state;
				END CASE;
		end if;
	END PROCESS DAC_MON;
	----------------------------------------------------------------------------
	----------------------------------------------------------------------------
	----------------------------------------------------------------------------
	SCK_DAC <= SCK_DAC_INTERNAL;
	DIN_DAC <= DIN_DAC_INTERNAL;
	CS_DAC <= CS_DAC_INTERNAL;
	
	INTERNAL_CHIPSCOPE_ILA_TRIG0(0) <= CLK_40M;
	INTERNAL_CHIPSCOPE_ILA_TRIG0(1) <= CLK_COUNTER(2);
	INTERNAL_CHIPSCOPE_ILA_TRIG0(2) <= CLK_COUNTER(3);
	INTERNAL_CHIPSCOPE_ILA_TRIG0(3) <= CS_DAC_INTERNAL;
	INTERNAL_CHIPSCOPE_ILA_TRIG0(4) <= SCK_DAC_INTERNAL;
	INTERNAL_CHIPSCOPE_ILA_TRIG0(5) <= DIN_DAC_INTERNAL;
	--==================SET TO '0' FOR NOW======================================
	SCL_MUX			<= '0';	
   SDA_MUX			<= '0';		
   
	SCL_MON			<= '0';		 
   SDA_MON			<= '0';		
   
   SSTIN				<= '0';			
   SSPIN				<= '0';			
   RAMP				<= '0';			
   RD_ROWSEL		<= "000";	
   RD_COLSEL		<= "000000";	
   RD_ENA			<= '0';		
   TST_START		<= '0';	
   TST_BOIN_CLR	<= '0';
   SIN				<= '0';			
   SCLK				<= '0';			
   REGCLR			<= '0';		
   WR_ADDRCLR		<= '0';	
   WR_STRB			<= '0';		
   START				<= '0';			
   SAMPLESEL		<= "00000";	
   SAMPLESEL_ANY		<= '0';	
   PCLK				<= '0';			
   WR_ADVCLK		<= '0';	
   WR_ENA			<= '0';		
   CLR				<= '0';			
   SR_SEL			<= '0';		
   SR_CLOCK			<= '0';		
   SR_CLEAR			<= '0';		
   
   MON				<= X"0000";			
   LMON				<= X"0";			
	--========================================================
	end Behavioral;